/**
 * 对象：
 *  对象属于一种复合型的数据类型，在对象中可以保存多个不同数据类型的属性。
 *
 *  对象的分类：
 *      内建对象
 *          -由ES标准定义的对象，在任何的ES实现中都可以使用
 *          比如：Math、String、Number、Boolean、Function、Object...
 *
 *      宿主对象
 *          -由JS的运行环境提供的对象，目前来讲主要由浏览器提供的对象。
 *          比如：BOM DOM
 *
 *      自定义对象
 *          -由开发人员自己创建的对象
 *
 *  创建对象：
 *      使用new关键字调用的函数，是构造函数，构造函数是专门用来创建对象的函数.
 *      使用typeof检查一个对象时，会返回object
 *
 *
 * */

var obj = new Object();

/**
 * 在对象中保存的值称为属性，向对象中添加属性的语法是：【增】
 *      对象.属性名 = 属性值
 * */
obj.name = '孙悟空';
obj.gender = '花果山';
obj.age = "18";
console.log(obj);

/**
 * 读取对象中的属性                                【查】
 *      语法:对象.属性名
 *      如果读取对象中没有的属性，不会报错而是返回undefined
 * */

console.log("姓名： " + obj.name + "， 地址： " + obj.gender + ", 年龄： "+ obj.age);

/**
 * 修改对象中的属性：                              【改】
 *      语法：对象.属性名 = 新值
 *
 * */
obj.name = "猪八戒";
console.log(obj.name);

/**
 * 删除对象中的属性：                               【删】
 *      语法：delete 对象.属性名
 * */

delete obj.gender;

console.log(obj.gender);

/**
 * 属性名：
 *      对象的属性名不强制要求遵守标识符规范，什么乱七八糟的名字都可以使用。但是我们还是尽量按照标识符的规范去做。
 *      但是，如果要使用特殊的（乱七八糟的名字）属性名，不能采用.的方式来操作，需要使用另一种语法：
 *          语法：对象["属性名"] = 属性值
 *          读取时也采用这种方式
 *
 *          使用[]这种形式去操作属性，更加的灵活。
 *          在[]中可以直接传递一个变量，这样变量的值是多少就会读取哪个属性。
 *
 * */

obj["123"] = 789;
obj["nihao"] = '你好';

var n = "nihao";

console.log(obj[n]);

/**
 * 属性值:
 *      JS对象的属性值可以是任意的数据类型，甚至也可以是一个对象。
 * */

var obj2 = new Object();
obj2.name = "猪八戒";
obj.test = obj2;
console.log(obj);
console.log(obj.test.name);

/**
 * in运算符
 *      通过该运算符可以检查一个对象中是否有指定的属性，如果有则返回true，没有则返回false
 *      语法："属性名" in 对象
 * */
console.log("=====================");

console.log(obj);
console.log("age" in obj);
console.log("age" in obj2);


/**
 * 基本和引用数据类型
 *      基本数据类型：
 *          String、 Number、 Boolean、Null、 Undefined
 *      引用数据类型：
 *          Object
 *
 *      JS中的变量都是保存到栈内存中的，
 *          基本数据类型的值直接在栈内存中储存，值与值之间都是独立存在的，修改一个变量不会影响其他的变量
 *
 *          对象是保存到堆内存中的，每创建一个对象，就会在堆内存中开辟一个新的空间，而变量保存的是对象的内存地址（对象的引用），如果
 *          两个变量保存的是同一个对象的引用，当一个通过一个变量修改属性时另一个也会受到影响。
 *
 *          当比较两个基本数据类型的值时，就是比较值
 *          二比较两个引用数据类型时，它是比较对象的内存地址，如果两个对象是一模一样的，但是地址不同，它也会返回false
 *
 * */

/**
 * 使用对象字面量来创建一个对象
 *  var obj = {}
 * 使用对象字面量，可以在创建对象时，直接指定对象中的属性
 * 语法：{属性名:属性值, 属性名：属性值...}
 *      对象字面量的属性名可以加引号，也可以不加引号，建议不加引号，但是如果使用一些特殊的名字，则必须添加引号。
 *
 *      属性名和属性值是一组一组的名值对结构，名和值之间使用:连接，多个名值对之间使用,隔开，如果一个属性之后没有其他属性了，就不要写,
 * */

var obj3 = {name:"孙悟空", age:16};

console.log(obj3);